/**
 * @file   dictionary_factory.cpp
 * @author wolfhead <wolfhead@wolfhead-laptop>
 * @date   Fri Oct 21 13:11:53 2011
 * 
 * @brief  
 * 
 * 
 */
#include "dictionary_factory.h"
#include "dictionary.h"
#include "attribute.h"
#include "attribute_factory.h"

using namespace PP;

#define DICT_FACTORY_SUUCESS                    (0x00000000)

#define DICT_REGISTER_PARENT_NOT_EXIST          (0x01000001)
#define DICT_REGISTER_NAME_ALREADY_EXIST        (0x01000002)
#define DICT_REGISTER_ID_ALREADY_EXIST          (0x01000003)
#define DICT_REGISTER_INITIALIZE_FAIL           (0x01000004)

#define ATTR_REGISTER_DICT_NOT_EXIST            (0x02000001)
#define ATTR_REGISTER_CREATE_FAIL               (0x02000002)
#define ATTR_REGISTER_APPEND_ATTR_FAIL          (0x02000003)



#define SET_ERROR(X) SetError(X, #X)

DictionaryFactory::DictionaryFactory()
{
}

DictionaryFactory::~DictionaryFactory()
{
}


void DictionaryFactory::SetError(int code, const std::string& message)
{
    lastErrorCode_ = code;
    lastErrorMessage_ = message;
}

int DictionaryFactory::GetLastError() const
{
    return lastErrorCode_;
}

const std::string& DictionaryFactory::GetLastErrorMessage() const
{
    return lastErrorMessage_;
}

int DictionaryFactory::RegisterDictionary(
    const DictionaryConfig& config
    )
{
    SET_ERROR(DICT_FACTORY_SUUCESS);

    DictionaryPtr pParent;
    // find the parent for this dictionary
    if (!config.parentName.empty())
    {
        pParent = GetDictionaryByName(config.parentName);
        if (!pParent)
        {
            SET_ERROR(DICT_REGISTER_PARENT_NOT_EXIST);
            return -1;
        }
    }

    if (dictionaryNameMap_.find(config.name) != dictionaryNameMap_.end())
    {
        SET_ERROR(DICT_REGISTER_NAME_ALREADY_EXIST);
        return -1;
    }

    if (dictionaryIdMap_.find(config.id) != dictionaryIdMap_.end())
    {
        SET_ERROR(DICT_REGISTER_ID_ALREADY_EXIST);
        return -1;
    }

    DictionaryPtr pCurrent(new Dictionary());

    if (0 != pCurrent->Initialize(config))
    {
        SET_ERROR(DICT_REGISTER_INITIALIZE_FAIL);
        return -1;
    }

    dictionaryNameMap_.insert(std::make_pair(config.name, pCurrent));
    dictionaryIdMap_.insert(std::make_pair(config.id, pCurrent));

    return 0;
}

int DictionaryFactory::RegisterAttribute(DictionaryId id, const AttributeConfig& attributeConfig)
{
    SET_ERROR(DICT_FACTORY_SUUCESS);

    DictionaryPtr pDict = GetDictionaryById(id);
    if (!pDict)
    {
        SET_ERROR(ATTR_REGISTER_DICT_NOT_EXIST);
        return -1;
    }

    AttributePtr pAttr = AttributeFactory::Instance()
        .CreateAttribute(attributeConfig);
    if (!pAttr)
    {
        SET_ERROR(ATTR_REGISTER_CREATE_FAIL);
        return -1;
    }

    if (0 != pDict->AppendAttribute(pAttr))
    {
        SET_ERROR(ATTR_REGISTER_APPEND_ATTR_FAIL);
        return -1;
    }

    return 0;
}



DictionaryPtr DictionaryFactory::GetDictionaryByName(const std::string& name) const
{
    NameMapType::const_iterator it = dictionaryNameMap_.find(name);
    if (it == dictionaryNameMap_.end())
    {
        return DictionaryPtr();
    }

    return it->second;
}

DictionaryPtr DictionaryFactory::GetDictionaryById(DictionaryId id) const
{
    IdMapType::const_iterator it = dictionaryIdMap_.find(id);
    if (it == dictionaryIdMap_.end())
    {
        return DictionaryPtr();
    }

    return it->second;
}


